#!/usr/bin/env python3
# -*- coding: utf-8 -*-
"""
Shopify 路由模块
包含OAuth认证流程和Webhook事件处理的API端点
"""

import os
import uuid
from datetime import datetime
from flask import Blueprint, request, jsonify, redirect, session

from app.conf.config import config, logger
from app.services.shopify_oauth_service import shopify_oauth_service
from app.services.shopify_webhook_service import shopify_webhook_service

# 创建Shopify路由蓝图
shopify_bp = Blueprint('shopify', __name__, url_prefix='/api/shopify')


@shopify_bp.route('/auth/install', methods=['GET'])
def install():
    """
    处理Shopify应用安装请求
    生成OAuth状态并重定向到Shopify授权页面
    """
    try:
        # 获取shop参数
        shop = request.args.get('shop')
        
        if not shop:
            return jsonify({
                'error': 'Missing shop parameter',
                'message': 'Shop URL is required'
            }), 400
        
        # 验证shop参数格式（必须包含.myshopify.com）
        if '.myshopify.com' not in shop:
            shop = f"{shop}.myshopify.com"
        
        # 生成OAuth状态和nonce
        state = shopify_oauth_service.generate_oauth_state(shop)
        
        # 生成授权URL
        auth_url = shopify_oauth_service.generate_auth_url(shop, state)
        
        logger.info(f"生成授权URL: {shop} -> {auth_url}")
        
        # 重定向到Shopify授权页面
        return redirect(auth_url)
        
    except Exception as e:
        logger.error(f"安装请求处理失败: {str(e)}")
        return jsonify({
            'error': 'Installation failed',
            'message': str(e)
        }), 500


@shopify_bp.route('/auth/callback', methods=['GET'])
def callback():
    """
    处理Shopify OAuth回调
    验证状态，获取访问令牌，并完成授权流程
    """
    try:
        # 获取回调参数
        shop = request.args.get('shop')
        code = request.args.get('code')
        state = request.args.get('state')
        timestamp = request.args.get('timestamp')
        hmac = request.args.get('hmac')
        
        if not all([shop, code, state, timestamp, hmac]):
            return jsonify({
                'error': 'Missing required parameters',
                'message': 'Shop, code, state, timestamp, and hmac are required'
            }), 400
        
        # 验证HMAC签名
        if not shopify_oauth_service.verify_hmac(request.args):
            return jsonify({
                'error': 'Invalid HMAC',
                'message': 'Request could not be verified'
            }), 401
        
        # 验证OAuth状态
        if not shopify_oauth_service.verify_oauth_state(state, shop):
            return jsonify({
                'error': 'Invalid state',
                'message': 'State verification failed'
            }), 401
        
        # 标记状态为已使用
        shopify_oauth_service.mark_state_as_used(state)
        
        # 交换访问令牌
        token_response = shopify_oauth_service.exchange_token(shop, code)
        
        if not token_response.get('success'):
            return jsonify({
                'error': 'Token exchange failed',
                'message': token_response.get('error', 'Unknown error')
            }), 401
        
        # 获取店铺信息
        store_info = shopify_oauth_service.get_store_info(shop, token_response['access_token'])
        
        # 保存店铺信息和令牌
        shopify_oauth_service.save_store(shop, store_info, token_response)
        
        # 注册必要的Webhook
        webhook_address = f"{config.APP_URL}/api/shopify/webhooks"
        webhook_topics = [
            'app/uninstalled',
            'orders/create',
            'products/update'
        ]
        
        for topic in webhook_topics:
            shopify_oauth_service.register_webhook(shop, topic, webhook_address)
        
        logger.info(f"店铺授权成功: {shop}")
        
        # 重定向到应用首页或成功页面
        return redirect(f"{config.APP_URL}/success?shop={shop}")
        
    except Exception as e:
        logger.error(f"授权回调处理失败: {str(e)}")
        return jsonify({
            'error': 'Authorization failed',
            'message': str(e)
        }), 500


@shopify_bp.route('/webhooks', methods=['POST'])
def webhook_handler():
    """
    处理所有Shopify Webhook事件
    验证请求合法性并路由到相应的处理逻辑
    """
    try:
        # 获取Webhook头信息
        topic = request.headers.get('X-Shopify-Topic')
        shop_domain = request.headers.get('X-Shopify-Shop-Domain')
        hmac_header = request.headers.get('X-Shopify-Hmac-Sha256')
        webhook_id = request.headers.get('X-Shopify-Webhook-Id')
        
        # 生成唯一请求ID
        request_id = str(uuid.uuid4())
        
        # 验证必要的头信息
        if not all([topic, shop_domain, hmac_header]):
            logger.warning(f"Webhook请求缺少必要头信息: topic={topic}, shop={shop_domain}")
            return jsonify({
                'error': 'Missing required headers',
                'message': 'X-Shopify-Topic, X-Shopify-Shop-Domain, and X-Shopify-Hmac-Sha256 are required'
            }), 400
        
        logger.debug(f"收到Webhook: topic={topic}, shop={shop_domain}, request_id={request_id}")
        
        # 获取请求体
        request_body = request.get_data()
        
        # 处理Webhook
        result = shopify_webhook_service.handle_webhook(
            shop_domain=shop_domain,
            topic=topic,
            request_id=request_id,
            payload_json=request_body.decode('utf-8'),
            hmac_header=hmac_header
        )
        
        if result['success']:
            # 对所有Webhook响应200 OK，即使处理内部有错误
            # Shopify会根据HTTP状态码决定是否重试
            logger.info(f"Webhook已接收并开始处理: topic={topic}, shop={shop_domain}")
            return jsonify({
                'status': 'received',
                'request_id': request_id,
                'log_id': result['log_id']
            }), 200
        else:
            # 即使验证失败，也返回200以避免重试，但记录错误
            logger.error(f"Webhook验证失败: {result['message']}, topic={topic}, shop={shop_domain}")
            return jsonify({
                'status': 'invalid',
                'message': result['message'],
                'request_id': request_id
            }), 200
            
    except Exception as e:
        # 捕获所有异常，确保返回200状态码
        error_id = str(uuid.uuid4())
        logger.error(f"Webhook处理异常 [{error_id}]: {str(e)}")
        return jsonify({
            'status': 'error',
            'error_id': error_id,
            'message': 'Internal server error'
        }), 200


@shopify_bp.route('/auth/refresh_token', methods=['POST'])
def refresh_token():
    """
    刷新店铺访问令牌
    通常由后台任务调用，而不是直接的API端点
    """
    try:
        # 从请求获取店铺域名
        data = request.get_json()
        shop_domain = data.get('shop_domain')
        
        if not shop_domain:
            return jsonify({
                'error': 'Missing shop_domain',
                'message': 'Shop domain is required'
            }), 400
        
        # 刷新令牌
        result = shopify_oauth_service.refresh_store_token(shop_domain)
        
        if result['success']:
            return jsonify({
                'success': True,
                'message': 'Token refreshed successfully'
            }), 200
        else:
            return jsonify({
                'success': False,
                'error': result.get('error', 'Token refresh failed')
            }), 401
            
    except Exception as e:
        logger.error(f"令牌刷新失败: {str(e)}")
        return jsonify({
            'error': 'Refresh failed',
            'message': str(e)
        }), 500


@shopify_bp.route('/stores/<shop_domain>', methods=['GET'])
def get_store_info(shop_domain):
    """
    获取店铺信息
    用于管理界面展示店铺详情
    """
    try:
        # 验证请求合法性（可添加认证中间件）
        # 此处简化处理，实际应添加API密钥认证或JWT验证
        
        # 获取店铺信息
        store = shopify_oauth_service.get_store(shop_domain)
        
        if not store:
            return jsonify({
                'error': 'Store not found',
                'message': f'No store found for {shop_domain}'
            }), 404
        
        # 脱敏处理
        safe_store = {
            'id': store['id'],
            'shop_domain': store['shop_domain'],
            'scope': store['scope'],
            'is_active': store['is_active'],
            'created_at': store['created_at'],
            'updated_at': store['updated_at'],
            'uninstalled_at': store['uninstalled_at']
            # 不返回访问令牌等敏感信息
        }
        
        return jsonify(safe_store), 200
        
    except Exception as e:
        logger.error(f"获取店铺信息失败: {str(e)}")
        return jsonify({
            'error': 'Failed to get store info',
            'message': str(e)
        }), 500


@shopify_bp.route('/stores/<shop_domain>/webhooks', methods=['GET'])
def get_store_webhooks(shop_domain):
    """
    获取店铺注册的Webhook列表
    """
    try:
        # 获取店铺Webhook配置
        webhooks = shopify_oauth_service.get_store_webhooks(shop_domain)
        
        return jsonify({
            'shop_domain': shop_domain,
            'webhooks': webhooks,
            'count': len(webhooks)
        }), 200
        
    except Exception as e:
        logger.error(f"获取店铺Webhook配置失败: {str(e)}")
        return jsonify({
            'error': 'Failed to get webhooks',
            'message': str(e)
        }), 500


@shopify_bp.route('/webhooks/stats', methods=['GET'])
def get_webhook_stats():
    """
    获取Webhook统计信息
    """
    try:
        # 获取查询参数
        shop_domain = request.args.get('shop_domain')
        days = request.args.get('days', 7, type=int)
        
        # 获取统计数据
        stats = shopify_webhook_service.get_webhook_stats(shop_domain=shop_domain, days=days)
        
        return jsonify(stats), 200
        
    except Exception as e:
        logger.error(f"获取Webhook统计失败: {str(e)}")
        return jsonify({
            'error': 'Failed to get webhook stats',
            'message': str(e)
        }), 500


# 添加一些示例Webhook处理程序

def handle_order_created(shop_domain, payload, log_id):
    """
    处理订单创建事件示例
    """
    try:
        order_id = payload.get('id')
        customer_email = payload.get('customer', {}).get('email')
        
        logger.info(f"新订单创建: 店铺={shop_domain}, 订单ID={order_id}, 客户={customer_email}")
        
        # 这里可以添加订单处理逻辑
        # 例如：发送通知、更新库存、创建任务等
        
    except Exception as e:
        logger.error(f"处理订单创建事件失败: {str(e)}")


def handle_product_updated(shop_domain, payload, log_id):
    """
    处理产品更新事件示例
    """
    try:
        product_id = payload.get('id')
        product_title = payload.get('title')
        
        logger.info(f"产品已更新: 店铺={shop_domain}, 产品ID={product_id}, 标题={product_title}")
        
        # 这里可以添加产品更新处理逻辑
        # 例如：清理缓存、同步数据、更新搜索引擎等
        
    except Exception as e:
        logger.error(f"处理产品更新事件失败: {str(e)}")


# 注册Webhook处理程序
shopify_webhook_service.register_handler('orders/create', handle_order_created)
shopify_webhook_service.register_handler('products/update', handle_product_updated)


# 导出路由蓝图供应用使用
def get_blueprint():
    """
    获取Shopify路由蓝图
    用于在主应用中注册
    """
    return shopify_bp